package com.mycompany.app.util;

import org.apache.velocity.app.VelocityEngine;
import org.hibernate.FlushMode;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.orm.hibernate3.SessionFactoryUtils;
import org.springframework.orm.hibernate3.SessionHolder;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import com.mycompany.app.common.mail.MailEngine;

/**
 * Get object reference with a singleton method, adapted from T&A project.
 * <p>
 * It will be replaced by SpringServiceLocator.java
 * 
 * @author martin.liu 2005-3-29
 * @author kevin.wang 2006-12-28
 */

public class SpringUtils implements ApplicationContextAware, InitializingBean {
    private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory
            .getLog(SpringUtils.class);

    private static ApplicationContext ctx = null;

    public void setApplicationContext(ApplicationContext ctx) {

        SpringUtils.ctx = ctx;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
     */
    public void afterPropertiesSet() throws Exception {

        if (SpringUtils.ctx == null)
            log
                    .warn("Application Context doesnt initialize correctly. This may influence some daemon task triggered by System Scheduler.");
    }

    /**
     * @Description: Get application context initialized by auto-starting
     *               servlet.
     * @exception IllegalStateException: SystemInitializer servlet doesn't
     *                config correctly.
     * @return
     */
    public static ApplicationContext getApplicationContext() {

        if (null == ctx)
            throw new IllegalStateException(
                    "Application context doesn't initialize correctly. Can't get application context.");

        return ctx;
    }

    // public static SessionFactory getSessionFactory() {
    //
    // SessionFactory sessionFactory = (SessionFactory) getApplicationContext()
    // .getBean("sessionFactory");
    // return sessionFactory;
    // }

    /**
     * @return Velocity Engine Instance
     */
    public static VelocityEngine getVelocityEngine() {

        VelocityEngine velocityEngine = (VelocityEngine) getApplicationContext()
                .getBean(ServiceBeanConstans.VELOCITY_ENGINE);
        return velocityEngine;

    }

    /**
     * bind session to current thread for invoker thread.
     */
    public static void bindSession() {

        SessionFactory sessionFactory = SpringUtils.getSessionFactory();

        // Open Session
        // 获取绑定到当前线程上的Session, 如果没有就创建.
        Session openSession;
        SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager
                .getResource(sessionFactory);
        if (sessionHolder != null && !sessionHolder.isEmpty())
            // dont allow repeated bound.
            return;
        else {
            openSession = SessionFactoryUtils.getSession(sessionFactory, true);
            openSession.setFlushMode(FlushMode.AUTO);
            TransactionSynchronizationManager.bindResource(sessionFactory,
                    new SessionHolder(openSession));
        }
    }

    /**
     * unbind session to current thread for invoker thread.
     */
    public static void unbindSession() {

        SessionFactory sessionFactory = SpringUtils.getSessionFactory();
        // 获取绑定到当前线程上的Session
        Session openSession = SessionFactoryUtils.getSession(sessionFactory,
                false);
        // Session openSession = sessionFactory.getCurrentSession();
        TransactionSynchronizationManager.unbindResource(sessionFactory);
        if (openSession != null)
            SessionFactoryUtils.closeSession(openSession);
    }

    /**
     * @return Mail Engine Instance
     */
    public static MailEngine getMailEngine() {

        MailEngine velocityEngine = (MailEngine) getApplicationContext()
                .getBean(ServiceBeanConstans.MAIL_ENGINE);
        return velocityEngine;
    }

    public static SessionFactory getSessionFactory() {

        return (SessionFactory) getApplicationContext().getBean(
                ServiceBeanConstans.SESSION_FACTORY);
    }

    static class ServiceBeanConstans {
        static String SESSION_FACTORY = "sessionFactory";

        static String MAIL_ENGINE = "mailEngine";

        static String VELOCITY_ENGINE = "velocityEngine";

    }

    // public static String getCurrentLoginName() {
    //
    // String userName = SecurityConstants.ANONYMOUS_USER;
    //
    // Authentication authentication = SecurityContextHolder.getContext()
    // .getAuthentication();
    // if (authentication != null) {
    // Object principal = authentication.getPrincipal();
    // if (principal instanceof org.acegisecurity.userdetails.User) {
    // org.acegisecurity.userdetails.User user =
    // (org.acegisecurity.userdetails.User) principal;
    // userName = user.getUsername();
    // } else {
    // userName = principal.toString();
    // }
    // }
    // return userName;
    // }

}
